<template>
  <div id="jsoneditor-options">
    <!-- 文件名 -->
    <div v-if="!fileNameEdit" class="flex items-center gap-2 cursor-pointer" @click="editFileName">{{ fileName }} <IJamWrite /></div>
    <n-input v-if="fileNameEdit" style="width: 200px" v-model:value="fileName" @blur="fileNameEdit = false"></n-input>
    <!-- 编辑器菜单 -->
    <div class="flex items-center gap-2">
      <n-dropdown :options="FileOptions" :show-arrow="true" @select="handleFileOptionsSelect">
        <!-- 文件管理 -->
        <n-button text type="info">
          <template #icon>
            <IMaterialSymbolsFileCopySharp />
          </template>
          文件
        </n-button>
      </n-dropdown>
    </div>
  </div>

  <!-- 编辑器 -->
  <div ref="jsoneditor" id="jsoneditor" />
</template>

<script lang="ts" setup>
import { NIcon } from "naive-ui";
import { useConfigStore } from "@renderer/store/config";
import JSONEditor from "jsoneditor";
import "jsoneditor/dist/jsoneditor.css";
import MaterialSymbolsEditDocument from "@renderer/components/Icon/MaterialSymbolsEditDocument.vue";
import MaterialSymbolsFileSaveOutlineRounded from "@renderer/components/Icon/MaterialSymbolsFileSaveOutlineRounded.vue";

/* ******************************通用属性/方法****************************** */
// 主题
const useConfig = useConfigStore();

// 编辑器背景主题
const editorBg = computed(() => {
  return useConfig.theme === "dark" ? "#404040" : "rgb(240, 240, 240)";
});
const editorBg2 = computed(() => {
  return useConfig.theme === "dark" ? "#5cd65c" : "#5cd65c";
});
// 编辑器字体颜色
const editorFontColor = computed(() => {
  return useConfig.theme === "dark" ? "rgb(240, 240, 240)" : "#404040";
});

// 渲染图标
const renderIcon = (icon: Component) => {
  return () => {
    return h(NIcon, null, {
      default: () => h(icon),
    });
  };
};

/* ******************************选项栏属性/方法****************************** */
// 文件菜单选项
const FileOptions = [
  {
    label: "新建文件",
    key: "newFile",
    icon: renderIcon(MaterialSymbolsEditDocument),
  },
  {
    label: "保存文件",
    key: "saveFile",
    icon: renderIcon(MaterialSymbolsFileSaveOutlineRounded),
  },
];
// 文件菜单选择
const handleFileOptionsSelect = (key: "newFile" | "saveFile") => {
  switch (key) {
    // 新建文件
    case "newFile":
      fileName.value = "NEW_FILE";
      editor.value?.setText("{}");
      break;

    // 保存文件
    case "saveFile":
      // 文件名
      let fname = "";
      // 文件名验证
      if (fileName.value.indexOf(".") === -1) {
        fname = fileName.value + ".json";
      } else {
        if (fileName.value.split(".").pop()!.toLowerCase() === "json") {
          // 不需要处理
        } else {
          fname = fileName.value.split(".")[0] + ".json";
        }
      }
      // 保存文件
      const blob = new Blob([editor.value!.getText()], { type: "application/json;charset=utf-8" });
      const a = document.createElement("a");
      a.href = URL.createObjectURL(blob);
      a.download = fname;
      a.click();
      URL.revokeObjectURL(a.href);
      break;
    default:
      break;
  }
};

/* ******************************编辑器属性/方法****************************** */
// jsoneditor容器
const jsoneditorRef = useTemplateRef("jsoneditor");
// jsoneditor实例
const editor = ref<JSONEditor>();

// 初始化jsoneditor
onMounted(() => {
  editor.value = new JSONEditor(jsoneditorRef.value!, {
    modes: ["code", "tree", "text", "form", "preview", "view"],
  });
});

// 文件名
const fileName = ref("NEW_FILE");
// 编辑状态
const fileNameEdit = ref(false);
// 修改文件名
const editFileName = () => {
  fileNameEdit.value = true;
};
</script>

<style lang="scss" scoped>
#jsoneditor-options {
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

#jsoneditor {
  height: calc(100vh - 60px - 36px - 42px - 40px);
}

// 编辑器菜单主题
:deep(.jsoneditor .autocomplete.dropdown) {
  background-color: v-bind(editorBg);
  color: v-bind(editorFontColor);
}

:deep(.jsoneditor .autocomplete.dropdown .item) {
  color: v-bind(editorFontColor);
  &:hover {
    background-color: v-bind(editorBg);
  }
}

:deep(.jsoneditor .autocomplete.hint) {
  color: v-bind(editorFontColor);
}

:deep(.jsoneditor-contextmenu .jsoneditor-menu) {
  background-color: v-bind(editorBg);
  color: v-bind(editorFontColor);
}

:deep(.jsoneditor-contextmenu .jsoneditor-menu button:hover, .jsoneditor-contextmenu .jsoneditor-menu button:focus) {
  background-color: v-bind(editorBg2);
  color: v-bind(editorFontColor);
}

:deep(
  .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected,
  .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:hover,
  .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:focus
) {
  color: v-bind(editorFontColor);
  background-color: v-bind(editorBg);
}

:deep(.jsoneditor-contextmenu .jsoneditor-menu li ul li button:hover, .jsoneditor-contextmenu .jsoneditor-menu li ul li button:focus) {
  background-color: v-bind(editorBg);
}

:deep(.jsoneditor-contextmenu .jsoneditor-text) {
  color: v-bind(editorFontColor);
}

:deep(.jsoneditor-modal .pico-modal-header) {
  background-color: v-bind(editorBg);
  color: v-bind(editorFontColor);
}

:deep(.jsoneditor-modal .pico-close) {
  color: v-bind(editorFontColor);
}

:deep(.jsoneditor-modal input[disabled]) {
  background-color: v-bind(editorBg);
  color: v-bind(editorFontColor);
}

:deep(.jsoneditor-modal .jsoneditor-transform-preview) {
  background-color: v-bind(editorBg);
}

:deep(.jsoneditor-modal .selectr-selected) {
  background-color: v-bind(editorBg);
}

:deep(.jsoneditor-modal table th, .jsoneditor-modal table td) {
  color: v-bind(editorFontColor);
}

:deep(
  .jsoneditor-modal select,
  .jsoneditor-modal textarea,
  .jsoneditor-modal input,
  .jsoneditor-modal input[type="text"],
  .jsoneditor-modal input[type="text"]:focus,
  .jsoneditor-modal #query
) {
  background-color: v-bind(editorBg);
  color: v-bind(editorFontColor);
}

:deep(.jsoneditor-modal input[type="button"], .jsoneditor-modal input[type="submit"]) {
  background-color: v-bind(editorBg);
}

:deep(.jsoneditor) {
  background-color: v-bind(editorBg);
  color: v-bind(editorFontColor);
}

:deep(div.ace_gutter) {
  color: v-bind(editorFontColor);
  background-color: v-bind(editorBg);
}

:deep(div.ace_content) {
  color: v-bind(editorFontColor);
  background-color: v-bind(editorBg);
}

:deep(.ace-jsoneditor .ace_marker-layer .ace_active-line) {
  background-color: #63ade9;
}

:deep(.ace-jsoneditor .ace_variable) {
  color: v-bind(editorFontColor);
}

:deep(div.jsoneditor-readonly) {
  color: v-bind(editorFontColor);
}

:deep(.jsoneditor-modes .jsoneditor-separator) {
  color: v-bind(editorFontColor);
}

:deep(div.jsoneditor td.jsoneditor-separator) {
  color: v-bind(editorFontColor);
}

:deep(div.jsoneditor.busy pre.jsoneditor-preview) {
  background-color: v-bind(editorBg);
  color: v-bind(editorFontColor);
}

:deep(div.jsoneditor-default) {
  color: v-bind(editorFontColor);
}

:deep(div.jsoneditor-tree) {
  background-color: v-bind(editorBg);
}

:deep(div.jsoneditor-tree button.jsoneditor-button:focus) {
  background-color: v-bind(editorBg);
  color: v-bind(editorFontColor);
}

:deep(div.jsoneditor-tree div.jsoneditor-show-more) {
  background-color: v-bind(editorBg);
  color: v-bind(editorFontColor);
}
:deep(div.jsoneditor-tree div.jsoneditor-show-more a) {
  color: v-bind(editorFontColor);
}

:deep(div.jsoneditor-tree div.jsoneditor-date) {
  background-color: v-bind(editorBg);
  color: v-bind(editorFontColor);
}

:deep(div.jsoneditor-busy span) {
  background-color: v-bind(editorBg);
  color: v-bind(editorFontColor);
}

:deep(
  div.jsoneditor-field[contenteditable="true"]:focus,
  div.jsoneditor-field[contenteditable="true"]:hover,
  div.jsoneditor-value[contenteditable="true"]:focus,
  div.jsoneditor-value[contenteditable="true"]:hover,
  div.jsoneditor-field.jsoneditor-highlight,
  div.jsoneditor-value.jsoneditor-highlight
) {
  background-color: v-bind(editorBg2);
  color: v-bind(editorFontColor);
}

:deep(
  div.jsoneditor-field.jsoneditor-highlight-active,
  div.jsoneditor-field.jsoneditor-highlight-active:focus,
  div.jsoneditor-field.jsoneditor-highlight-active:hover,
  div.jsoneditor-value.jsoneditor-highlight-active,
  div.jsoneditor-value.jsoneditor-highlight-active:focus,
  div.jsoneditor-value.jsoneditor-highlight-active:hover
) {
  background-color: v-bind(editorBg2);
  color: v-bind(editorFontColor);
}

:deep(div.jsoneditor-field.jsoneditor-empty::after, div.jsoneditor-value.jsoneditor-empty::after) {
  color: v-bind(editorFontColor);
}

:deep(textarea.jsoneditor-text) {
  color: v-bind(editorFontColor);
  background-color: v-bind(editorBg);
}

:deep(tr.jsoneditor-highlight, tr.jsoneditor-selected) {
  background-color: v-bind(editorBg);
}

:deep(
  div.jsoneditor-field,
  div.jsoneditor-value,
  div.jsoneditor td,
  div.jsoneditor th,
  div.jsoneditor textarea,
  pre.jsoneditor-preview,
  .jsoneditor-schema-error,
  .jsoneditor-popover
) {
  background: v-bind(editorBg);
  color: v-bind(editorFontColor);
}

:deep(pre.jsoneditor-preview) {
  background-color: v-bind(editorBg);
  color: v-bind(editorFontColor);
}

:deep(.jsoneditor-popover) {
  background-color: v-bind(editorBg);
  color: v-bind(editorFontColor);
}

:deep(.jsoneditor .jsoneditor-additional-errors) {
  background-color: v-bind(editorBg);
  color: v-bind(editorFontColor);
}

:deep(.jsoneditor-menu) {
  background-color: v-bind(editorBg);
  color: v-bind(editorFontColor);
}

:deep(.jsoneditor-menu > button, .jsoneditor-menu > .jsoneditor-modes > button) {
  background-color: v-bind(editorBg2);
  color: v-bind(editorFontColor);
}

:deep(.jsoneditor-menu > button:hover, .jsoneditor-menu > .jsoneditor-modes > button:hover) {
  background-color: v-bind(editorBg);
}

:deep(
  .jsoneditor-menu > button:focus,
  .jsoneditor-menu > button:active,
  .jsoneditor-menu > .jsoneditor-modes > button:focus,
  .jsoneditor-menu > .jsoneditor-modes > button:active
) {
  background-color: v-bind(editorBg);
}

:deep(.jsoneditor-menu a) {
  color: v-bind(editorFontColor);
}

:deep(.jsoneditor-navigation-bar) {
  background-color: v-bind(editorBg);
  color: v-bind(editorFontColor);
}

:deep(.jsoneditor-search input) {
  color: v-bind(editorFontColor);
}

:deep(.jsoneditor-results) {
  color: v-bind(editorFontColor);
}

:deep(.jsoneditor-frame) {
  background-color: v-bind(editorBg);
}

:deep(.jsoneditor-statusbar) {
  background-color: v-bind(editorBg);
  color: v-bind(editorFontColor);
}

:deep(.jsoneditor-treepath.show-all) {
  background-color: v-bind(editorBg);
}

:deep(.jsoneditor-treepath .jsoneditor-treepath-show-all-btn) {
  background-color: v-bind(editorBg);
}

:deep(.selectr-selected) {
  background-color: v-bind(editorBg);
}

:deep(.selectr-placeholder) {
  color: v-bind(editorFontColor);
}

:deep(.selectr-tag) {
  color: v-bind(editorFontColor);
}

:deep(.selectr-options-container) {
  background-color: v-bind(editorBg);
}

:deep(
  .selectr-clear::before,
  .selectr-clear::after,
  .selectr-input-clear::before,
  .selectr-input-clear::after,
  .selectr-tag-remove::before,
  .selectr-tag-remove::after
) {
  background-color: v-bind(editorBg);
}

:deep(.selectr-tag-remove::before, .selectr-tag-remove::after) {
  background-color: v-bind(editorBg);
}

:deep(.selectr-notice) {
  background-color: v-bind(editorBg);
}

:deep(.selectr-option.selected) {
  background-color: v-bind(editorBg);
}

:deep(.selectr-option.active) {
  color: v-bind(editorFontColor);
}

:deep(.selectr-container.inverted .selectr-options-container) {
  background-color: v-bind(editorBg);
}

:deep(.selectr-container ::-webkit-input-placeholder) {
  color: v-bind(editorFontColor);
}
</style>
